package com.yxlgateway.gateway.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yxlcommon.common.pojo.RespBean;
import com.yxlcommon.common.pojo.SmsCodeReq;
import com.yxlcommon.common.pojo.User;
import com.yxlgateway.service.EmailService;
import com.yxlgateway.service.SmsSendService;
import com.yxlgateway.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author yxl
 * @since 2021-11-09
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private UserService userService;

    @Autowired
    private EmailService emailService;

    @Resource
    private SmsSendService smsSendService;

    @PostMapping("/login")
    public RespBean<User> login(@RequestBody User user) {
        Object o = redisTemplate.opsForValue().get("loginTimes" + user.getUsername());
        if (Objects.equals(5, o)) {
            redisTemplate.expire("loginTimes" + user.getUsername(), 60, TimeUnit.SECONDS);
            return RespBean.operationSuccess("登录频繁，请稍候重试", -10, null);
        }
        return userService.checkLogin(user.getUsername(), user.getPassword());
    }

    @PostMapping("/smsSend")
    CompletableFuture<RespBean<Object>> respBeanCompletableFuture(@RequestBody SmsCodeReq smsCodeReq) throws ClientException {
        return smsSendService.sendCode(smsCodeReq);
    }

    @PostMapping("/register")
    public RespBean<Integer> register(@RequestBody User user) {
        return userService.userRegister(user);
    }

    @PostMapping("/verifyCode")
    public RespBean<String> verifyCode(@RequestBody User user) {
        String code = String.valueOf(ThreadLocalRandom.current().nextInt(899999) + 100000);
        redisTemplate.opsForValue().set("regCode" + user.getEmail(), code, 5, TimeUnit.MINUTES);
        if (!Objects.equals(null, code)) {
            emailService.sendRegisterCode(user.getEmail(), "尊敬的用户,您好:\n"
                    + "\n本次注册的邮件验证码为:" + code + ",验证码将在五分钟后过期,（请勿泄露此验证码）\n"
                    + "\n如非本人操作，请忽略该邮件。"
            );
            return RespBean.operationSuccess("发送成功", 200, "ok");
        }
        return RespBean.operationSuccess("发送失败", -10, "ok");
    }

    @GetMapping("/logout")
    public RespBean logout() {
        StpUtil.logout();
        return RespBean.operationSuccess("退出成功", 200, "ok");
    }

    @PostMapping("/forgetPwd")
    public RespBean forgetPwd(@RequestBody User user) {
        return userService.forgetPwd(user);
    }

    @PostMapping("/forgetPwdCode")
    public RespBean<String> forgetPwdCode(@RequestBody User user) {
        String code = String.valueOf(ThreadLocalRandom.current().nextInt(899999) + 100000);
        redisTemplate.opsForValue().set("forgetPwd" + user.getEmail(), code, 5, TimeUnit.MINUTES);
        if (!Objects.equals(null, code)) {
            emailService.sendFindPasswordCode(user.getEmail(), "尊敬的用户,您好:\n"
                    + "\n本次找回密码的邮件验证码为:" + code + ",验证码将在五分钟后过期,（请勿泄露此验证码）\n"
                    + "\n如非本人操作，请忽略该邮件。"
            );
            return RespBean.operationSuccess("发送成功", 200, "ok");
        }
        return RespBean.operationSuccess("发送失败", -10, "ok");
    }

    @PostMapping("/selectUser")
    public RespBean<User> selectUser(@RequestBody User user) {
        return userService.selectUser(user);
    }

    @PostMapping("/changePwdCode")
    public RespBean changePwdCode(@RequestBody User user) {
        String code = String.valueOf(ThreadLocalRandom.current().nextInt(899999) + 100000);
        redisTemplate.opsForValue().set("changePwd" + user.getEmail(), code, 5, TimeUnit.MINUTES);
        if (!Objects.equals(null, code)) {
            emailService.sendChangePasswordCode(user.getEmail(), "尊敬的用户,您好:\n"
                    + "\n本次修改密码的邮件验证码为:" + code + ",验证码将在五分钟后过期,（请勿泄露此验证码）\n"
                    + "\n如非本人操作，请忽略该邮件。"
            );
            return RespBean.operationSuccess("发送成功", 200, "ok");
        }
        return RespBean.operationSuccess("发送失败", -10, "ok");
    }

    @PostMapping("/changePwd")
    public RespBean<String> changePwd(@RequestBody User user) {
        return userService.changePwd(user);
    }

    @PostMapping("/changeInfo")
    public RespBean changeInfo(@RequestBody User user) {
        return userService.updateUserInfo(user);
    }

    @PostMapping("/updateAvatar")
    public RespBean<Integer> updateAvatar(MultipartFile file, User user) throws Exception {
        return userService.updateAvatar(file, user);
    }

    @PostMapping("/selectUserImg")
    public RespBean selectUserImg(@RequestBody User user) {
        return userService.selectUserImg(user);
    }

    @PostMapping("/selectAllUser")
    public RespBean<IPage<User>> selectAllUser(@RequestParam(defaultValue = "1") Integer currentPage,
                                               @RequestParam(defaultValue = "10") Integer size,
                                               User user) {
        return userService.getAllUserByPage(user, currentPage, size);
    }

    @PostMapping("/deleteUserById")
    public RespBean deleteUserById(@RequestBody User user) {
        return userService.deleteUserById(user);
    }

    @PostMapping("/changeUserById")
    public RespBean changeUserById(@RequestBody User user) {
        return userService.changeUserById(user);
    }

    @PostMapping("/addUser")
    public RespBean addUser(@RequestBody User user) {
        return userService.addUser(user);
    }

    @GetMapping("/getAll")
    public RespBean<List<User>> getAll() {
        return RespBean.operationSuccess("ok", 200, userService.list());
    }
}
